 package group6renderer;  

import java.awt.Color;
import java.util.HashMap;
import javax.swing.*;
import java.util.Stack;

/**
 * A class containing a HashMap of boolean variables allowing easy access to return and toggle attributes.
 * 
 * @author Joe Thomas
 * @version 0.2
 */
public class State
{


    private static final boolean DEFAULT_BOLD = false;
    private static final boolean DEFAULT_ITALIC = false;
    private static final boolean DEFAULT_UNDERLINED = false;
    private static final boolean DEFAULT_WRAPPED = false;
    private static final boolean DEFAULT_BLOCKQUOTE= false;
    private static final boolean DEFAULT_FONT= true;
    

        
	public static final int LEFT_SWING = SwingConstants.LEFT;
	public static final int RIGHT_SWING = SwingConstants.RIGHT;
	public static final int CENTER_SWING = SwingConstants.CENTER;
    
    public static final int LEVELS_OF_HEADINGS =7;
    // instance variables (fields). 
    private HashMap<String, Boolean> booleanStates;
    private Stack<Integer> alignmentStack;
    private int[] headings;
    private boolean headingTagFound=false;

    
    /**
     * A Constructor to initialise the instance variables of a new State.
     */
    public State()
    {     
        booleanStates = new HashMap<String, Boolean>();
        booleanStates.put(HTMLConstants.BOLD, DEFAULT_BOLD);
        booleanStates.put(HTMLConstants.ITALIC, DEFAULT_ITALIC);
        booleanStates.put(HTMLConstants.UNDERLINE, DEFAULT_UNDERLINED);
        booleanStates.put(HTMLConstants.WRAPPED, DEFAULT_WRAPPED);
        booleanStates.put(HTMLConstants.BLOCKQUOTE, DEFAULT_BLOCKQUOTE);
        booleanStates.put(HTMLConstants.PRE, DEFAULT_FONT);

        
        
        headings=new int[LEVELS_OF_HEADINGS];
        
        alignmentStack=new Stack<Integer>();
        alignmentStack.push((Integer)LEFT_SWING);
   //     alignmentStack.push((Integer)LEFT_SWING);
       

        
    }
    /**
     * A method to toggle a single boolean state. That is if the state is true, it will be made to be false and visa-versa. This is a first attempt towards making sure that 
     * a state is deactivated after the visitor has left the node relating to this state for good. It takes a string which is the key of one of the attributes in the HashMap.
     * @param key The key of the attribute that needs to be toggled.  *Range: must use one of State.BOLD, State.ITALIC, State.UNDERLINED, State.WRAPPED.
     */
    public void toggleState(String key)
    {
        boolean state = booleanStates.get(key);

        state=!state;
        booleanStates.remove(key);
        booleanStates.put(key, state);
    }
    
    /**
     * A method to return the state of a single boolean state. It takes a string which is the key of one of the attributes in the HashMap.
     * @param key The key of the attribute that needs to be toggled.  *Range: must use one of State.BOLD, State.ITALIC, State.UNDERLINED, State.WRAPPED.
     */
    public boolean getState(String key)
    {
    	
        return booleanStates.get(key);
        
    }
    
    
    
	public void setAlignment(String alignment)
	{
		int align=(Integer)this.alignmentStack.pop();
		
		if (alignment==HTMLConstants.CENTER)
		{
			if (align!=CENTER_SWING)
				{alignmentStack.push((Integer)align);
				alignmentStack.push((Integer)CENTER_SWING);
				}
			
		}
		
		else
			
			if (alignment==HTMLConstants.RIGHT)
			{
				if (align!=RIGHT_SWING)
				{	alignmentStack.push(align);
					alignmentStack.push(RIGHT_SWING);
				}
			}
			
		else
		{	if (align!=LEFT_SWING)
				{alignmentStack.push(align);
				alignmentStack.push(LEFT_SWING);
				}
			else
				if (alignmentStack.size()==0)
				{
					alignmentStack.push(LEFT_SWING);
				}
		}	
	}

	public int getAlignment()
	{
		//alignmentStack.push(LEFT); 
		int alignment=(Integer)alignmentStack.pop();
		 alignmentStack.push((Integer)alignment);
		 return  alignment;
	}
    
    
    
 
    /** 
     * A method to set the heading number of a piece of text.
     * @param heading the number to set the heading to.  *Range: between 1.0 and 7.7.
     */
    
    
    public void setHeading(int level)
    {
    	level--;//this is because the numbers are 1-7 but array uses 0-6
    	
    	headings[level]++;
    	//System.out.println(headings[level]);
    	for (int i=0;i<LEVELS_OF_HEADINGS;i++)
    	{
    		if (i>level)
    			headings[i]=0;
    		else
    			if	((i<level) && (headings[i]==0)) headings[i]++; 
    		
    	}
    	
    	
    	
    	headingTagFound=true;
    //	System.out.println(getHeading());
    }
    
    public String getHeading()
    {
    	
    	String heading="";
    	
    	if (headingTagFound)
    	{heading="";
    		for (int i=0;i<LEVELS_OF_HEADINGS;i++)
    		{
    			
    			if( headings[i]==0) break;
    			heading=heading+headings[i]+".";
    			
    			
    		}
    		headingTagFound=false;
    	}
    	System.out.println(heading);
    	return heading+"  ";
    }
  
 

    
    
    
}